home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C / Applications / Simple Slideshow / TIFF code folder / tifflzw.c < prev   
Encoding:
C/C++ Source or Header  |  1994-06-06  |  2.4 KB  |  114 lines  |  [TEXT/KAHL]

  1. #include "tiffinfo.h"
  2.  
  3. /*
  4.  * Lempel-Ziv decompression for TIFF. inlen is the actual number of input
  5.  * characters, and outlen is the number of expected output characters.
  6.  * out[] has size outlen, so it is an error if there are more than outlen
  7.  * characters produced. UnLZW() returns 0 if everything was fine, and
  8.  * < 0 if there was some problem.
  9.  */
  10.  
  11. /*
  12.  * If a code is < 256, it is that character. 256 is the Clear code, and
  13.  * 257 is the end-of-information code. Otherwise it refers to a string
  14.  * previously produced as output, followed by a single character.
  15.  */ 
  16. struct stringtable{
  17.     long index;
  18.     long len;
  19. };
  20. #define ClearCode 256
  21. #define EndOfInformation 257
  22.  
  23.  
  24. void                    ClearTable            (struct stringtable *table);
  25.  
  26.  
  27.  
  28. void
  29. ClearTable(struct stringtable *table)
  30. {
  31.     short i;
  32.     
  33.     for(i = 0; i < 256; i++){
  34.         table[i].index = 0;
  35.         table[i].len = 0;
  36.     }
  37. }
  38.  
  39. short
  40. UnLZW(char *in, long inlen, char *out, long outlen)
  41. {
  42.     struct stringtable *table = 0;
  43.     short ncodes; /* # of codes in the table */
  44.     short codelen; /* current code length in bits */
  45.     unsigned short *ip; /* current point in input */
  46.     short bit; /* # of (high) bits consumed in *ip */
  47.     char *op; /* next element to write in out[] */
  48.     unsigned short code;
  49.     short i;
  50.     
  51.     table = (struct stringtable *) NewPtr(sizeof(struct stringtable) * 4096);
  52.     if(table == 0)
  53.         return(MemError());
  54.         
  55.     ClearTable(table);
  56.     ncodes = 258; /* one for each 8-bit character, plus two special codes */
  57.     codelen = 9;
  58.     
  59.     op = out;
  60.     ip = (unsigned short *) in;
  61.     bit = 0;
  62.     
  63.     while(1){
  64.         if((char *)ip >= in + inlen){
  65.             /* ran out of information before we saw EndOfInformation! */
  66.             goto bad;
  67.         }
  68.         
  69.         if(bit >= 16){
  70.             ip++;
  71.             bit = 0;
  72.         }
  73.         code = (*ip << bit) >> (16 - codelen);
  74.         bit += codelen;
  75.         if(bit > 16){
  76.             /* need to read some more */
  77.             ip++;
  78.             bit -= 16;
  79.             code |= (*ip >> (16 - bit));
  80.         }
  81.         
  82.         if(code == ClearCode){
  83.             ncodes = 258;
  84.             codelen = 9;
  85.         } else if(code == EndOfInformation){
  86.             break;
  87.         } else if(code < ncodes){
  88.             if(op + table[code].len > out + outlen)
  89.                 goto bad;
  90.             table[ncodes].index = op - out;
  91.             if(code < 256){
  92.                 *op++ = code;
  93.                 table[ncodes].len = 2;
  94.             } else {
  95.                 for(i = 0; i < table[code].len; i++)
  96.                     *op++ = out[table[code].index + i];
  97.                 table[ncodes].len = table[code].len + 1;
  98.             }
  99.             ncodes++;
  100.             if(ncodes == (1 << codelen))
  101.                 codelen++;
  102.         } else {
  103.             /* code out of range */
  104.             goto bad;
  105.         }
  106.     }
  107.     
  108.     DisposPtr( ( Ptr )  table);
  109.     return(0);
  110. bad:
  111.     if(table)
  112.         DisposPtr( ( Ptr ) table);
  113.     return(-1);
  114. }